package com.seecen.HJM.controller;

import cn.hutool.captcha.generator.MathGenerator;
import com.seecen.HJM.model.dto.AdminDto;
import com.seecen.HJM.model.dto.CaptchaCodeDto;
import com.seecen.HJM.result.DataVo;
import com.seecen.HJM.service.AdminService;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/api/admin")
@RequiredArgsConstructor
public class AdminAuthController {
    private final AdminService adminService;
    private static final String CAPTCHA_CODE_KEY = CaptchaController.Captcha_Code;
    private static final ThreadLocal<MathGenerator> MATH_GENERATOR = ThreadLocal.withInitial(MathGenerator::new);

    @PostMapping("/login")
    public DataVo login(@RequestBody @Valid AdminDto adminDto, BindingResult bindingResult, HttpSession httpSession) {
        //处理参数校验失败
        if (bindingResult.hasErrors()) {
            // 提取所有错误信息
            String errorMsg = bindingResult.getFieldErrors().stream()
                    .map(FieldError::getDefaultMessage)
                    .collect(Collectors.joining(";"));
            //返回校验错误
            return DataVo.error(errorMsg);
        }
        //session获取验证码
        CaptchaCodeDto codeDto = (CaptchaCodeDto) httpSession.getAttribute(CAPTCHA_CODE_KEY);

        if (codeDto == null) {
            log.warn("管理员登录-验证码不存在，用户名：{}", adminDto.getUsername());
            return DataVo.error("验证码不存在");
        }
        if (LocalDateTime.now().isAfter(codeDto.getExpDate())) {
            httpSession.removeAttribute(CAPTCHA_CODE_KEY);
            log.warn("管理员登录-验证码过期，用户名：{}", adminDto.getUsername());
            return DataVo.error("验证码过期");
        }

        if (!MATH_GENERATOR.get().verify(codeDto.getCode(), adminDto.getCode())) {
            log.warn("管理员登录-验证码错误，用户名：{}，用户输入：{}，正确答案：{}",
                    adminDto.getUsername(), adminDto.getCode(), codeDto.getCode());
            return DataVo.error("验证码输入错误");
        }
        //验证码验证通过，立即清理（防止重复使用）
        httpSession.removeAttribute(CAPTCHA_CODE_KEY);
        //校验通过，调用Service层执行登录逻辑，直接返回Service的结果，捕获异常
        try {
            return adminService.login(adminDto);
        } catch (Exception e) {
            // 记录异常日志
            log.error("\n管理员登录失败，用户名：{}", adminDto.getUsername(), e);
            return DataVo.error("登录失败，请重新登录");
        }
    }

    @PostMapping("/register")
    public DataVo register(@RequestBody @Valid AdminDto adminDto, BindingResult bindingResult) {
        //处理参数校验失败
        if (bindingResult.hasErrors()) {
            String errorMsg = bindingResult.getFieldErrors().stream()
                    .map(FieldError::getDefaultMessage)
                    .collect(Collectors.joining(";"));
            return DataVo.error(errorMsg);
        }
        //校验通过，调用Service层执行注册逻辑，捕获异常
        try {
            return adminService.register(adminDto);
        } catch (Exception e) {
            // 记录异常日志
            log.error("管理员注册失败，用户名：{}", adminDto.getUsername(), e);
            return DataVo.error("注册失败，请重新注册");
        }
    }

    @PostMapping("loginOut")
    public DataVo loginOut(@RequestHeader("Authorization") String token) {
        return adminService.loginOut(token);
    }
}
